/* Copyright  2009
   @Author
   Richard Changde Yin            e-mail yinchangde@hotmail.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/**
 * @filename: esql.h
 */

#ifndef __LIBCLIENT_ESQL_H__
#define __LIBCLIENT_ESQL_H__

#include <include/common.h>
#include "esql_field.h"
#include "options.h"
#include "esql_res.h"
#include "net_serv.h"

#include <stdint.h>
#if !defined(__cplusplus)
# include <stdbool.h>
#endif

#ifdef  __cplusplus
extern "C" {
#endif

struct st_esql_methods;

enum esql_status
{
  ESQL_STATUS_READY,
  ESQL_STATUS_GET_RESULT,
  ESQL_STATUS_USE_RESULT
};

typedef struct st_esql
{
  NET    net;      /* Communication parameters */
  unsigned char  *connector_fd;    /* ConnectorFd for SSL */
  char    *host,*user,*passwd,*unix_socket,*server_version,*host_info;
  char          *info, *db;
  ESQL_FIELD  *fields;
  uint64_t  affected_rows;
  uint64_t  insert_id;    /* id if insert on table with NEXTNR */
  uint64_t  extra_info;    /* Not used */
  uint32_t  thread_id;    /* Id for connection in server */
  uint32_t  packet_length;
  uint32_t  port;
  uint32_t  client_flag,server_capabilities;
  uint32_t  protocol_version;
  uint32_t  field_count;
  uint32_t  server_status;
  uint32_t  server_language;
  uint32_t  warning_count;
  struct st_client_options options;
  enum esql_status status;
  bool  free_me;    /* If free in client_close */
  bool  reconnect;    /* set to 1 if automatic reconnect */

  /* session-wide random string */
  char          scramble[SCRAMBLE_LENGTH+1];
  bool unused1;
  void *unused2, *unused3, *unused4, *unused5;

  const struct st_esql_methods *methods;
  void *thd;
  /*
    Points to boolean flag in ESQL_RES  or ESQL_STMT. We set this flag
    from esql_stmt_close if close had to cancel result set of this object.
  */
  bool *unbuffered_fetch_owner;
  /* needed for embedded server - no net buffer to store the 'info' */
  char *info_buffer;
  void *extension;
} ESQL;

ESQL * client_create(ESQL *esql);
ESQL * client_connect(ESQL *esql, const char *host,
             const char *user,
             const char *passwd,
             const char *db,
             uint32_t port,
             const char *unix_socket,
             uint32_t clientflag);

int32_t    client_select_db(ESQL *esql, const char *db);
int32_t    client_query(ESQL *esql, const char *q);
int32_t    client_send_query(ESQL *esql, const char *q, uint32_t length);
int32_t    client_real_query(ESQL *esql, const char *q, uint32_t length);

ESQL_RES *  client_store_result(ESQL *esql);
ESQL_RES *  client_use_result(ESQL *esql);

uint32_t  client_field_count(const ESQL *esql);
uint64_t  client_affected_rows(const ESQL *esql);
uint64_t  client_insert_id(const ESQL *esql);
uint32_t  client_errno(const ESQL *esql);
const char *  client_error(const ESQL *esql);
const char *  client_sqlstate(const ESQL *esql);
uint32_t      client_warning_count(const ESQL *esql);
const char *  client_info(const ESQL *esql);
uint32_t      client_thread_id(const ESQL *esql);
const char *  character_set_name(const ESQL *esql);

bool   client_change_user(ESQL *esql, const char *user,
                           const char *passwd, const char *db);

/* local infile support */

#define LOCAL_INFILE_ERROR_LEN 512

void
client_set_local_infile_handler(ESQL *esql,
        int (*local_infile_init)(void **, const char *, void *),
        int (*local_infile_read)(void *, char *, unsigned int),
        void (*local_infile_end)(void *),int (*local_infile_error)
        (void *, char*, unsigned int), void *);

void
client_set_local_infile_default(ESQL *esql);

int32_t    client_shutdown(ESQL *esql);
int32_t    dump_debug_info(ESQL *esql);
int32_t    client_refresh(ESQL *esql, uint32_t refresh_options);
int32_t    client_ping(ESQL *esql);
const char *  esql_stat(ESQL *esql);
const char *  client_get_server_info(const ESQL *esql);

const char *  client_get_host_info(const ESQL *esql);
uint32_t    client_get_server_version(const ESQL *esql);
uint32_t    client_get_proto_info(const ESQL *esql);
ESQL_RES *  client_list_tables(ESQL *esql,const char *wild);
ESQL_RES *  client_list_processes(ESQL *esql);
int32_t    client_options(ESQL *esql, enum esql_option option,
                                 const void *arg);
bool  client_read_query_result(ESQL *esql);

bool  client_commit(ESQL *esql);
bool  client_rollback(ESQL *esql);
bool  client_autocommit(ESQL *esql, bool auto_mode);
bool  client_more_results(const ESQL *esql);
int   client_next_result(ESQL *esql);
void  client_close(ESQL *esql);
bool  client_reconnect(ESQL *esql);
void  client_disconnect(ESQL *esql);

bool
client_cli_advanced_command(ESQL *esql, enum enum_server_command command,
                     const unsigned char *header, uint32_t header_length,
                     const unsigned char *arg, uint32_t arg_length,
                     bool skip_check);
uint32_t      client_cli_safe_read(ESQL *esql);
ESQL_FIELD *  client_cli_list_fields(ESQL *esql);
ESQL_DATA *   client_cli_read_rows(ESQL *esql,ESQL_FIELD *esql_fields,
                             unsigned int fields);
int client_cli_unbuffered_fetch(ESQL *esql, char **row);
const char * client_cli_read_statistics(ESQL *esql);

typedef bool (*safe_read_error_hook_func)(NET *net);
extern safe_read_error_hook_func safe_read_error_hook;

#ifdef  __cplusplus
}
#endif

#endif /* __LIBCLIENT_ESQL_H__ */
